home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / MacGzip 1.0 / source / Mac / EventLoop.c next >
Text File  |  1995-12-30  |  19KB  |  944 lines

  1. /*
  2.  * Copyright (C) 1995  SPDsoft
  3.  * 
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <stdarg.h>
  8. #include <limits.h>
  9.  
  10. /*
  11.  * THINK_C 8.0 extra includes (Not in MacHeaders)
  12.  */
  13. #include <Aliases.h>
  14. #include <Sound.h>
  15.  
  16.  
  17. #include "MacGzip.h"
  18. #include "GzErrors.h"
  19. #include "ErrorStrings.h"
  20. #include "GzPStrings.h"
  21.  
  22. #include "Prefs.h"
  23. #include "FileTypes.h"
  24. #include "Globals.h"
  25. #include "Work.h"
  26.  
  27. #define        CGF_MAX_TYPES        4
  28.  
  29. #define        CustomGetFileDLOG    160
  30. #define        kShowAnyButton        10
  31.  
  32. #if GENERATINGCFM || USESROUTINEDESCRIPTORS
  33. #  define CreateRoutineDescriptor(info, proc)                                    \
  34.         RoutineDescriptor g##proc##RD = BUILD_ROUTINE_DESCRIPTOR(info, proc)
  35. #  define GetRoutineAddress(proc)    (&g##proc##RD)
  36. #else
  37. #  define GetRoutineAddress(proc)    proc
  38. #endif
  39.  
  40. /************************************************************************************
  41.  * 
  42.  * Movable Modal Stuff
  43.  *
  44.  *        MM from C.K. Haun (Apple DTS) (MModal 7.0)
  45.  *        Color Alysoft Solutions <heathcot@bnr.ca> (CModalProgress)
  46.  */
  47.  
  48. /*
  49.  * Prototypes
  50.  */
  51.  
  52. static void        DrawMovable(WindowPtr myWindow);
  53. static void        DrawBar(short part);
  54. static short    FixMMString( void );
  55. static void        DrawMsg(void);
  56. static void        BeginOfTask( void );
  57. static Boolean    EndOfTask( int errorcode );
  58. static int        RecurseDir(long dirIDToSearch);
  59. static int        DoOpen( FSSpec *fs );
  60. /*
  61.  * (Too many) Globals (we could group them in a struct and set it in refCon)
  62.  */
  63. #if GENERATINGCFM && !defined(__MWERKS__)
  64.     QDGlobals    qd;
  65. #endif
  66.  
  67. static Boolean            gTask = FALSE; 
  68. Boolean                    UseMModalProg=false;
  69.  
  70. static Rect                barRect; 
  71. static Rect                greyRect;
  72. static Rect                r;            /* Window's rect */
  73. static Rect                MsgRect;
  74.  
  75. static ControlHandle    ButtonHndl = nil;
  76.  
  77. long int                SPDEnd,
  78.                         *SPDNow = nil;
  79.  
  80. Str255                    SPDPstr="\p";
  81. char*                    SPDpstr=(char*)SPDPstr;
  82.  
  83. static    Boolean            gDirtyStr;
  84.  
  85. #define    kMyModalKind    1000
  86. #define    kMyModalID        150
  87. #define    kCancelButton    150
  88.  
  89. #define    kIndicatorOutline    0x0001
  90. #define    kIndicatorContent    0x0002
  91.  
  92. #define    BarHeight        13
  93. #define    BarMargin        20
  94.  
  95. /************************************************************************************
  96.  * 
  97.  * more generic globals
  98.  */
  99.  
  100. typedef struct
  101. {
  102.     short    numTypes;
  103.     OSType    typeList[CGF_MAX_TYPES];
  104.     Boolean    ShowAny;
  105.     Boolean    Inited;
  106. }    TypeList;
  107.  
  108.  
  109. extern TSufMap                gSufMap;
  110.  
  111.  
  112. static pascal short        MySFGetDlgHook( short MySFitem, DialogPtr dlgPtr, void *myDataPtr );
  113. static pascal Boolean    MyCustomFileFilter(ParmBlkPtr pb, void *myDataPtr);
  114.  
  115.  
  116. extern void        about(void);
  117. extern Boolean    DoPrefsDialog(PrefsTypePtr thePrefs, AliasHandle * theFldrAlias);
  118. Boolean            EventLoop( void );
  119. static Boolean    DoCommand( long mResult );
  120. static Boolean    DoMouseDown(short windowPart, WindowPtr whichWindow, EventRecord *theEvent);
  121.  
  122.  
  123. extern int gzip ( FSSpec *fs );
  124.  
  125. /************************************************************************************
  126.  * 
  127.  *  main event loop. Returns true when it has to end
  128.  */
  129.  
  130. Boolean EventLoop( void )
  131. {
  132.     typedef long (*MyProcPtr)( WindowPtr w );
  133.     
  134.     EventRecord                    theEvent;
  135.     MyProcPtr                    drawProc;
  136.     WindowPtr                    twindow;
  137.     short                        windowPart;
  138.     static long int                TheLastTime;
  139.     
  140.     Boolean                        done = FALSE;
  141.     static long                    SPDLast = 0;
  142.  
  143.  
  144.     if (gApp.quit)
  145.         return true;
  146.         
  147.     if (gApp.Working)
  148.     {
  149.         UpdateAnimatedCursor( gApp.Cursor, TickCount() );
  150.         /*
  151.          * Update bar
  152.          */
  153.          
  154.         if ((UseMModalProg) && ( SPDLast != *SPDNow ))
  155.         {
  156.             greyRect.left = greyRect.right;
  157.             
  158.             greyRect.right = 
  159.                 ((float)*SPDNow/SPDEnd)*(barRect.right-barRect.left) + barRect.left;
  160.  
  161.             DrawBar(kIndicatorContent);
  162.             SPDLast = *SPDNow;
  163.         }
  164.     
  165.         /*
  166.          * Update string
  167.          */
  168.         if ((gDirtyStr) && (UseMModalProg))
  169.             DrawMsg();
  170.     }
  171.     else if ( !gTask )
  172.     {
  173.         if ( !empty_work )
  174.         {
  175.             FSSpec        fs;
  176.             int            rescode=0;
  177.             
  178.             BeginOfTask();
  179.  
  180.             do
  181.             {
  182.                 if ( noErr == get_work(    &gApp.KeysMode, &gApp.Op, &gApp.Prompt, &fs )) 
  183.                 {
  184.                     rescode = DoOpen( &fs );
  185.                     EndOfTask( rescode );
  186.                 }
  187.                 else
  188.                     break;
  189.                     
  190.             } while (!gApp.quit && !empty_work);
  191.             
  192.             done = (( gApp.StartupFiles ) || ( gPrefs.Misc.QuitWhenDone ));
  193.         }
  194.     }
  195.         
  196.     while((GetNextEvent(everyEvent, &theEvent)) && !done)
  197.     {
  198.         switch( theEvent.what )
  199.         {
  200.             case keyDown:
  201.             case autoKey: 
  202.                 {
  203.                     register char theChar;
  204.     
  205.                     theChar = theEvent.message & charCodeMask;
  206.                     
  207.                     if ((theEvent.modifiers & cmdKey) != 0)
  208.                     {
  209.                         if ((theChar == '.' ) && gApp.Working)
  210.                         {
  211.                             SetCursor(&qd.arrow);
  212.                             done = true;
  213.                         }
  214.                         else
  215.                             done = DoCommand( MenuKey(theChar) );
  216.                     }
  217.                                     
  218.                     break;
  219.                 }
  220.                 
  221.             case mouseDown:
  222.             
  223.                 windowPart = FindWindow(theEvent.where, &twindow);
  224.                 
  225.                 done = DoMouseDown(windowPart, twindow, &theEvent);
  226.                 
  227.                 break;
  228.                 
  229.                 
  230.             case activateEvt:
  231.             case updateEvt:
  232.             
  233.                 if ( gApp.Working ) /* if working */
  234.                 {
  235.                     /*
  236.                      * Make sure it's my window before I jump through the refCon
  237.                      * Why, since DA's have they're own layer in 7.0?
  238.                      * BECAUSE there are other people in the universe who will
  239.                      * add things to your windowList.BalloonWriter, for example,
  240.                      * so you still need to be careful
  241.                      */
  242.                      
  243.                     if (((WindowPeek)theEvent.message)->windowKind == kMyModalKind)
  244.                     {
  245.                         drawProc = (MyProcPtr)GetWRefCon((WindowPtr)theEvent.message);
  246.                         drawProc((WindowPtr)theEvent.message);
  247.                     }
  248.                 }
  249.  
  250.                 break;
  251.                 
  252.             case diskEvt:
  253.             
  254.                 if ((theEvent.message >> 16) != noErr)
  255.                 {
  256.                     Point myPoint={100,100};
  257.                 
  258.                     err = DIBadMount(myPoint, theEvent.message);
  259.                     
  260.                     DoError(SYS_ERR,WARN_ERR,GetErrFmt(GENERIC, BAD_DISK));
  261.                 }
  262.                 
  263.                 break;
  264.  
  265.             case osEvt:
  266.                 switch ((theEvent.message >> 24) & 0x0ff)
  267.                 {
  268.                     case suspendResumeMessage:
  269.                         
  270.                         
  271.                     
  272.                         if ((theEvent.message & resumeFlag) == 0) // suspend 
  273.                         {
  274.                             gApp.InForeground = FALSE;
  275.                             SetCursor(&qd.arrow);
  276.                         }
  277.                         else
  278.                         {                                        // resume
  279.                             gApp.InForeground = TRUE;
  280.                             if (gApp.Working)
  281.                                 UpdateAnimatedCursor( gApp.Cursor, theEvent.when );
  282.                             else
  283.                                 SetCursor(&qd.arrow);
  284.                         }
  285.                         break;
  286.                         
  287.                     case mouseMovedMessage:
  288.                         break;
  289.                 }
  290.                 break;
  291.                 
  292.             case kHighLevelEvent:
  293.             
  294.                 AEProcessAppleEvent (&theEvent);
  295.                 done = gApp.quit;
  296.                 break;
  297.  
  298.             default:
  299.                 break;
  300.  
  301.         }
  302.     }
  303.     
  304.     return done;
  305. }
  306.  
  307. static Boolean DoCommand( long mResult )
  308. {
  309.     short    theItem;
  310.     Str255    name;
  311.     Boolean done=FALSE;
  312.  
  313. /* custom get file stuff */
  314.  
  315.     StandardFileReply    mySFR;
  316.  
  317. #if GENERATINGCFM || USESROUTINEDESCRIPTORS
  318.     CreateRoutineDescriptor(uppFileFilterYDProcInfo, MyCustomFileFilter);
  319.     CreateRoutineDescriptor(uppDlgHookYDProcInfo, MySFGetDlgHook);
  320. #endif
  321.             
  322.             
  323.     static TypeList        MyTypeList = {
  324.                                         4,
  325.                                         { 'Gzip','ZIVU','ZIVM','pZIP' },
  326.                                         FALSE,
  327.                                         FALSE
  328.                                     };
  329.     Point                sfgfpos = { -1, -1 };
  330.     
  331.  
  332.     theItem = LoWord(mResult);
  333.     
  334.     switch( HiWord(mResult) )
  335.     {
  336.         case kAppleMenu:
  337.             if( theItem > 2 )
  338.             {
  339.                 GrafPtr savePort;
  340.                 GetItem(GetMHandle(kAppleMenu), theItem, name);
  341.                 GetPort(&savePort);
  342.                     OpenDeskAcc(name);
  343.                 SetPort(savePort);
  344.             }
  345.             else
  346.             {
  347.                 about();
  348.             }
  349.             break;
  350.  
  351.         case kFileMenu:
  352.         
  353.             switch( theItem )
  354.             {
  355.                 case kfmExpand:
  356.                 case kfmOpen:
  357.  
  358.  
  359.                     CustomGetFile(
  360.                                 (FileFilterYDUPP)GetRoutineAddress(MyCustomFileFilter),
  361.                                 -1, *(SFTypeList *)&MyTypeList.typeList,
  362.                                 &mySFR,
  363.                                 CustomGetFileDLOG,
  364.                                 sfgfpos,
  365.                                 (DlgHookYDUPP)GetRoutineAddress(MySFGetDlgHook),
  366.                                 nil,
  367.                                 nil,
  368.                                 nil,
  369.                                 (void *) &MyTypeList
  370.                             );
  371.  
  372.                     if( mySFR.sfGood )
  373.                     {
  374.                         
  375.                         /* do something */
  376.                         BeginOfTask();
  377.                         
  378.                         gApp.KeysMode =        0;
  379.                         gApp.KeysOp =        0;
  380.                         gApp.Op = ( theItem == kfmExpand ? kMisc_gunzip : kMisc_auto );
  381.                         gApp.Prompt =     ( theItem == kfmExpand );        
  382.                         
  383.                         gSufMap.Type = mySFR.sfType;
  384.                         
  385.                         done = EndOfTask( gzip( &mySFR.sfFile)  );
  386.                     }
  387.                 
  388.                     break;
  389.         
  390.                 case kfmCompress:
  391.                 
  392.                     StandardGetFile( nil, -1, nil, &mySFR);
  393.                     if( mySFR.sfGood )
  394.                     {
  395.                         /* do something */
  396.                         
  397.                         BeginOfTask();
  398.                         
  399.                         gApp.KeysMode =        0;
  400.                         gApp.KeysOp =        0;
  401.                         gApp.Op =             kMisc_gzip;
  402.                         gApp.Prompt =         TRUE;        
  403.                         
  404.                         gSufMap.Type = mySFR.sfType;
  405.                         
  406.                         done = EndOfTask( gzip( &mySFR.sfFile)  );
  407.                     }
  408.  
  409.                     break;
  410.  
  411.                 case kfmQuit:
  412.                 
  413.                     gApp.quit = TRUE;
  414.                     done = TRUE;
  415.                     break;
  416.         
  417.                 default:
  418.                 
  419.                     break;
  420.         
  421.             }
  422.             break;
  423.  
  424.         case kEditMenu:
  425.         
  426.             switch( theItem )
  427.             {
  428.                 case kemPrefs:
  429.                 
  430.                     gApp.PrefsChanged = DoPrefsDialog(&gPrefs, &gApp.DFolder);
  431.                     
  432.                     if ( ( gPrefs.Compress.IC || gPrefs.Decompress.IC ) && (gSufMap.ICmappings == nil ))
  433.                         if ( InitICMappings( &(gSufMap.ICinst), &(gSufMap.ICmappings) ) )
  434.                         {
  435.                             /* couldn't init it */
  436.                             gPrefs.Compress.IC = gPrefs.Decompress.IC = FALSE;
  437.                             DoError(NO_ERR,INFO_ERR,GetErrFmt(GENERIC, CANT_GET_IC));
  438.                         }
  439.         
  440.                     if (( gPrefs.Decompress.Fetch )&&(gSufMap.FPrefs==nil))
  441.                         if ( InitFetchMappings( &(gSufMap.FPrefsSize), &(gSufMap.FPrefs) ) )
  442.                         {
  443.                             /* couldn't init it */
  444.                             gPrefs.Decompress.Fetch = FALSE;
  445.                             DoError(NO_ERR,INFO_ERR,GetErrFmt(GENERIC, CANT_GET_FETCH));
  446.                         }
  447.  
  448.                     break;
  449.                 
  450.                 default:
  451.                 
  452.                     SystemEdit(theItem-1);
  453.                     break;
  454.             }
  455.             break;
  456.             
  457.         default:
  458.             break;
  459.             
  460.     }
  461.  
  462.     HiliteMenu(0);
  463.     return done;
  464. }
  465.  
  466. static Boolean DoMouseDown(short windowPart, WindowPtr whichWindow, EventRecord *theEvent)
  467. {
  468.     Boolean         done=FALSE;
  469.     ControlHandle    WhichCtl;
  470.     
  471.     switch( windowPart )
  472.     {
  473.         case inMenuBar:
  474.             done = DoCommand( MenuSelect(theEvent->where) );
  475.             break;
  476.  
  477.         case inSysWindow:
  478.         
  479.             SystemClick(theEvent, whichWindow);
  480.             break;
  481.  
  482.         case inDrag:
  483.     
  484.             if ( whichWindow != FrontWindow() )
  485.             {
  486.                 /* don't do anything, can't drag a back window */
  487.                 SysBeep(1);
  488.             }
  489.             else
  490.             {
  491.                 DragWindow(whichWindow, theEvent->where, &qd.screenBits.bounds);
  492.                 gApp.PrefsChanged = TRUE;
  493.             }
  494.             break;
  495.                         
  496.         case inContent:
  497.                             
  498.             GlobalToLocal(&theEvent->where);
  499.                                
  500.             if(inButton == FindControl(theEvent->where, whichWindow, &WhichCtl))
  501.             {
  502.                 if(0!=TrackControl(WhichCtl, theEvent->where, nil))
  503.                 {
  504.                     SetCursor(&qd.arrow);
  505.                     done = TRUE;
  506.                 }
  507.             }            
  508.             break;
  509.  
  510.         case inGrow:
  511.         case inGoAway:
  512.             /* no such items in MacGzip */
  513.             break;
  514.  
  515.         default:
  516.             break;
  517.     }
  518.     
  519.     return done;
  520. }
  521.  
  522. /*
  523.  * CustomGetFile
  524.  */
  525.  
  526.  
  527. static pascal Boolean MyCustomFileFilter(ParmBlkPtr pb, void *myDataPtr)
  528. {
  529.     Boolean result ;
  530.     register short i;
  531.  
  532.     if (
  533.         ( ((TypeList *) myDataPtr)->ShowAny ) ||
  534.         (((pb->fileParam.ioFlAttrib>>4) & 0x01) == 1)    /* is folder */
  535.         )
  536.     {
  537.         result = FALSE;
  538.     }
  539.     else
  540.     {
  541.         for(i=0, result = FALSE; i<    ((TypeList *) myDataPtr)->numTypes ; i++)
  542.         {
  543.             if ( result = (
  544.                             ((TypeList *) myDataPtr)->typeList[i] ==  
  545.                             pb->fileParam.ioFlFndrInfo.fdType
  546.                         ))
  547.             break;        
  548.                             
  549.         }
  550.         result = !result;
  551.     }
  552.     
  553.     
  554.     return result;
  555. }
  556.  
  557. static pascal short  MySFGetDlgHook( short MySFitem, DialogPtr dlgPtr, void *myDataPtr )
  558. {
  559.     short    result = MySFitem;
  560.     short    value;
  561.     short    iType;
  562.     Handle    iHandle;
  563.     Rect    iRect;
  564.     
  565.     switch(MySFitem)
  566.     {
  567.         case sfHookFirstCall:
  568.  
  569.                         GetDItem(    dlgPtr, kShowAnyButton,
  570.                                     &iType, &iHandle, &iRect);
  571.  
  572.                         if ( ((TypeList *) myDataPtr)->Inited )
  573.                             SetCtlValue( (ControlHandle) iHandle,
  574.                                         (short) ((TypeList *) myDataPtr)->ShowAny );
  575.                         else
  576.                         {
  577.                             ((TypeList *) myDataPtr)->ShowAny = 
  578.                                 (Boolean) GetCtlValue( (ControlHandle) iHandle );
  579.                             
  580.                             ((TypeList *) myDataPtr)->Inited = TRUE;
  581.                         }
  582.                         
  583.                         break;
  584.                         
  585.         case kShowAnyButton:
  586.                         
  587.                         GetDItem(    dlgPtr, kShowAnyButton,
  588.                                     &iType, &iHandle, &iRect);
  589.                                     
  590.                         value = !GetCtlValue( (ControlHandle) iHandle );
  591.                         SetCtlValue( (ControlHandle) iHandle , value );
  592.                         
  593.                         ((TypeList *) myDataPtr)->ShowAny = (Boolean) value;
  594.                             
  595.                         result = sfHookRebuildList;        
  596.                         break;
  597.                         
  598.         default:    
  599.     
  600.                         break;
  601.     }
  602.  
  603.     return(result);
  604. }
  605.  
  606. /************************************************************************************
  607.  * 
  608.  * Movable Modal Stuff
  609.  */
  610.  
  611. void InitMovableModal(long int theEnd, long *now )
  612. {
  613.     WindowPtr    myWindow;
  614.  
  615.  
  616.     if (UseMModalProg)
  617.     {
  618.         /* There is already a window on the screen */
  619.         SPDNow=now;
  620.         SPDEnd=(theEnd==0?1:theEnd);
  621.         greyRect.right =    greyRect.left;
  622.         InvalRect(&r);
  623.     }
  624.     else
  625.     {
  626.         if ( gApp.hasColorQD )
  627.             myWindow = GetNewCWindow(kMyModalID, nil, (WindowPtr)-1);
  628.         else
  629.             myWindow = GetNewWindow(kMyModalID, nil, (WindowPtr)-1);
  630.             
  631.         SetWRefCon(myWindow, (long)DrawMovable);
  632.         ((WindowPeek)myWindow)->windowKind = kMyModalKind;
  633.             
  634.         /* move it to the saved position */
  635.         /* move it to 0,0 to avoid any math at all */
  636.         MoveWindow(myWindow, 0, 0, false);
  637.         MoveWindow(myWindow, gPrefs.SavedPoint.h, gPrefs.SavedPoint.v, false);
  638.         
  639.         r = myWindow->portRect;
  640.         
  641.         SPDNow=now;
  642.         SPDEnd=(theEnd==0?1:theEnd);
  643.     
  644.         UseMModalProg=true;
  645.         
  646.             
  647.         barRect.left =        r.left        + BarMargin;
  648.         barRect.right =        r.right        - BarMargin;
  649.         barRect.bottom =    r.bottom    - BarMargin;
  650.         barRect.top =    barRect.bottom    - BarHeight;
  651.         
  652.         ButtonHndl = GetNewControl( kCancelButton, myWindow);
  653.         
  654.         barRect.right  -= ( BarMargin + (*ButtonHndl)->contrlRect.right);
  655.         OffsetRect(
  656.             &((*ButtonHndl)->contrlRect),
  657.             barRect.right + BarMargin,
  658.                  barRect.top -
  659.             ((*ButtonHndl)->contrlRect.bottom - (*ButtonHndl)->contrlRect.top - BarHeight)/2
  660.              );
  661.     
  662.         ShowControl(ButtonHndl);
  663.      
  664.         greyRect.left =        barRect.left    + 1;
  665.         greyRect.right =    greyRect.left;
  666.         greyRect.bottom =    barRect.bottom    - 1;
  667.         greyRect.top =        barRect.top        + 1;
  668.         
  669.         ShowWindow(myWindow);
  670.         DrawMovable(myWindow);
  671.     
  672.         SetPort(myWindow);
  673.     }
  674. }
  675.  
  676. void SetMMString( const char *fmt, ... )
  677. {
  678.     va_list            vl;
  679.     char            StrTmp[256];
  680.     
  681.     va_start(vl,fmt);
  682.         vsprintf(StrTmp, fmt, vl);
  683.     va_end(vl);
  684.  
  685.     CStrToStr255( SPDPstr, StrTmp );
  686.     
  687.     gDirtyStr = TRUE;
  688. }
  689.  
  690. static short FixMMString( void )
  691. {
  692.     int        newWid, newLen, wid;
  693.     
  694.     wid = (r.right - r.left) - 2 * BarMargin;
  695.     newWid = StringWidth(SPDPstr);
  696.     if (newWid > wid )
  697.     {
  698.         newLen = (int) SPDPstr[0];
  699.         wid = wid - CharWidth('…');
  700.         do
  701.         {
  702.             newWid = newWid - CharWidth(SPDPstr[newLen]);
  703.             newLen--;
  704.         }while((newWid > wid) && (SPDPstr[0] != 0x00));
  705.  
  706.         newLen ++;
  707.         SPDPstr[newLen] = '…';
  708.         SPDPstr[0] = (char)newLen;
  709.     }
  710.     
  711.     return (StringWidth(SPDPstr));
  712. }    
  713.  
  714. static void DrawMsg(void)
  715. {
  716.     FontInfo    fInfo;
  717.     
  718.     TextFont( systemFont );
  719.     TextSize( 12 );
  720.     GetFontInfo( &fInfo );
  721.  
  722.     MsgRect.top = r.top + BarMargin - fInfo.ascent;
  723.     MsgRect.left = r.left + BarMargin;
  724.     
  725.     MsgRect.bottom = r.top + BarMargin + fInfo.descent;
  726. //    MsgRect.right = MsgRect.left + FixMMString();
  727.  
  728.     FixMMString();
  729.     MsgRect.right = r.right - BarMargin;
  730.     
  731.     EraseRect(&MsgRect) ;
  732.     
  733.     MoveTo( BarMargin , BarMargin);        /* h, v */
  734.     DrawString(SPDPstr);
  735.     
  736.     gDirtyStr = FALSE;
  737. }
  738.  
  739.  
  740. void ReleaseMovableModal(void)
  741. {
  742.     WindowPtr myWindow = FrontWindow();
  743.  
  744.     
  745.     
  746.      if(UseMModalProg)
  747.     {
  748.         if(ButtonHndl != nil)
  749.             DisposeControl(ButtonHndl);
  750.  
  751.         /* the front window really should be my modal window */
  752.         /* if it isn't, I'm bailing.*/
  753.  
  754.         gPrefs.SavedPoint.h = myWindow->portRect.left;
  755.         gPrefs.SavedPoint.v = myWindow->portRect.top;
  756.         LocalToGlobal(&gPrefs.SavedPoint);
  757.         if (((WindowPeek)myWindow)->windowKind == kMyModalKind)
  758.             CloseWindow(myWindow);
  759.     
  760.         UseMModalProg=false;
  761.     }
  762.     
  763.     
  764. }
  765.  
  766. static void DrawMovable(WindowPtr myWindow)
  767. {
  768.     WindowPtr            tempWP;
  769.  
  770.     BeginUpdate(myWindow);
  771.            GetPort(&tempWP);
  772.         SetPort(myWindow);
  773.  
  774.         DrawMsg();
  775.  
  776.         DrawBar(kIndicatorOutline | kIndicatorContent);
  777.         
  778.         DrawControls(myWindow);
  779.         
  780.         SetPort(tempWP);
  781.     EndUpdate(myWindow);
  782. }
  783.  
  784. static void DrawBar(short part)
  785. {
  786.     RGBColor    barColor        = {0x4444, 0x4444, 0x4444};
  787.     RGBColor    emptyBarColor    = {0xCCCC, 0xCCCC, 0xFFFF};
  788.     RGBColor    currentForeColor;
  789.     RGBColor    currentBackColor;
  790.  
  791.     if ((part & kIndicatorOutline) == kIndicatorOutline)
  792.     {
  793.         GetBackColor(¤tBackColor) ;
  794.         RGBBackColor(&emptyBarColor) ;
  795.         EraseRect(&barRect) ;
  796.         RGBBackColor(¤tBackColor) ;
  797.  
  798.         FrameRect(&barRect);
  799.         greyRect.left = barRect.left + 1;
  800.     }
  801.     
  802.     if ((part & kIndicatorContent) == kIndicatorContent)
  803.     {
  804.         GetForeColor(¤tForeColor);
  805.         RGBForeColor(&barColor);
  806.         PaintRect(&greyRect);
  807.         RGBForeColor(¤tForeColor);
  808.     }
  809. }
  810.  
  811. /************************************************************************************/
  812. HFileInfo    gpb;
  813.  
  814. static int DoOpen( FSSpec *fs )
  815. {
  816.     int                exitcode = 0;
  817.     HFileInfo        pb;
  818.  
  819.     pb.ioNamePtr    = fs->name;
  820.     pb.ioVRefNum    = fs->vRefNum;
  821.     pb.ioFDirIndex    = 0;                    /* query 1 item */
  822.     pb.ioDirID        = fs->parID;
  823.     
  824.     PBGetCatInfo( (CInfoPBPtr)&pb, 0 );
  825.     if (((pb.ioFlAttrib>>4) & 0x01) == 1)
  826.     {
  827.         /* Is a Dir */
  828.         if  ( gPrefs.Folder.RecurseMode == kFold_FNot )
  829.         {
  830.             exitcode = 3;
  831.         }
  832.         else
  833.         {
  834.             gpb.ioNamePtr = fs->name;
  835.             gpb.ioVRefNum = fs->vRefNum;
  836.     
  837.             exitcode = RecurseDir(pb.ioDirID);
  838.         }
  839.     }
  840.     else
  841.     {
  842.         /* Is a File */
  843.         gSufMap.Type = pb.ioFlFndrInfo.fdType;
  844.         
  845.         exitcode = gzip( fs );
  846.     }
  847.  
  848.     return exitcode;    
  849. }
  850.  
  851.  
  852. static int RecurseDir(long dirIDToSearch)
  853. {
  854.     short int    index=1;      /* for ioFDirIndex */
  855.     FSSpec        myFSSpec;
  856.     int            exitcode = 0;
  857.  
  858.     do
  859.     {
  860.         gpb.ioDirID        = dirIDToSearch;     
  861.         gpb.ioFDirIndex    = index;    /* set up the index */
  862.                                     /* we need to do this every time through,
  863.                                      * since GetCatInfo returns ioFlNum
  864.                                      * in this field
  865.                                      */
  866.         err= PBGetCatInfo((CInfoPBPtr)&gpb,false);
  867.  
  868.         if (err == noErr) 
  869.         {
  870.             /* check the file attributes for folderhood */
  871.             if (((gpb.ioFlAttrib>>4) & 0x01) == 1)
  872.             {
  873.                 if  ( gPrefs.Folder.RecurseMode == kFold_FAll )
  874.                 {
  875.                     exitcode = RecurseDir(gpb.ioDirID);
  876.                 }
  877.                 else
  878.                     exitcode = 0;
  879.                     
  880.                 err = 0;
  881.             }
  882.             else 
  883.             {
  884.                 FSMakeFSSpec(
  885.                         0,
  886.                         dirIDToSearch,
  887.                         gpb.ioNamePtr,
  888.                         &myFSSpec
  889.                         );
  890.                         
  891.                 exitcode =
  892.                     (0!=new_work( gApp.KeysMode, gApp.Op, gApp.Prompt, &myFSSpec ));
  893.             }
  894.              
  895.         index += 1;    /* increment the index for GetCatInfo */
  896.         }
  897.     } while ((err == noErr)&&( exitcode == 0));
  898.     
  899.     if ( err != fnfErr ) exitcode = 1;
  900.     return exitcode;
  901. }
  902.  
  903. /************************************************************************************/
  904.  
  905. static void BeginOfTask( void )
  906. {
  907.     gTask =  TRUE;
  908.     DisableItem(GetMHandle(kFileMenu), kfmOpen);
  909.     DisableItem(GetMHandle(kFileMenu), kfmCompress);
  910.     DisableItem(GetMHandle(kFileMenu), kfmExpand);
  911.     DisableItem(GetMHandle(kEditMenu), kemPrefs);
  912. }
  913.  
  914.  
  915. static Boolean EndOfTask( int errorcode )
  916. {
  917.     if ( gApp.Working )
  918.     {
  919.         if ( empty_work )
  920.         {
  921.             if ( 0 ==  errorcode )
  922.             {
  923.                 if ( gPrefs.Misc.BeepWhenDone )
  924.                     MyBeep(kBeepsnd_ID);
  925.             }
  926.             ReleaseMovableModal();
  927.             gApp.Working = FALSE;
  928.             SetCursor(&qd.arrow);                    
  929.         }
  930.         if ( SPDNow != nil) *SPDNow = 0;
  931.         SPDEnd=INT_MAX;
  932.     }
  933.     if ( empty_work )
  934.     {
  935.         gTask =  FALSE;
  936.         EnableItem(GetMHandle(kFileMenu), kfmOpen);
  937.         EnableItem(GetMHandle(kFileMenu), kfmCompress);
  938.         EnableItem(GetMHandle(kFileMenu), kfmExpand);
  939.         EnableItem(GetMHandle(kEditMenu), kemPrefs);
  940.     }
  941.     return (( gApp.StartupFiles ) || ( gPrefs.Misc.QuitWhenDone )) && empty_work ;
  942. }
  943.  
  944.